package com.primestone.cim.executeenddevicecontrols.async;

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.sql.DataSource;
import javax.xml.ws.Holder;

import org.jboss.ejb3.annotation.ResourceAdapter;

import ch.iec.tc57._2011.enddevicecontrolsmessage.EndDeviceControlsPayloadType;
import ch.iec.tc57._2011.schema.message.HeaderType;

import com.primestone.cim.entities.tmp.ResEndDeviceControls;
import com.primestone.cim.executeenddevicecontrols.Completer;
import com.primestone.cim.executeenddevicecontrols.QueueMessage;
import com.primestone.cim.executeenddevicecontrols.service.ExecEndDeviceControlsService;
import com.primestone.cim.executeenddevicecontrols.service.IExecEndDeviceControlsService;
import com.primestone.cim.util.StringUtil;
import com.primestone.cim.util.XMLUtil;
import com.primestone.cim.util.enums.CIMVerb;

/**
 * Message-Driven Bean implementation class for: CIMMDB
 *
 */
@MessageDriven(	
		activationConfig = { 
				@ActivationConfigProperty(propertyName = "destinationType", propertyValue = StringUtil.QUEUE_DEST_TYPE),
				@ActivationConfigProperty(propertyName = "connectionFactoryJndiName", propertyValue = StringUtil.CONN_FACTORY_JNDI_NAME),
				@ActivationConfigProperty(propertyName = "destination", propertyValue = StringUtil.DESTINATION_EXEC_EDC_QUEUE),
				@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = StringUtil.ACK_MODE)
		}
		)
@ResourceAdapter(StringUtil.RES_ADAPTER)
@TransactionManagement(TransactionManagementType.BEAN)
public class CIMMDB implements MessageListener {

	@Resource(name = StringUtil.RES_DS)
	DataSource dataSource;

	@EJB( beanName = StringUtil.TMPTABLEEJB_BEAN_NAME )
	TmpTableEJBLocal tmpTableEJB;

	@Resource
    MessageDrivenContext context;


	/**
	 * @see MessageListener#onMessage(Message)
	 */
	public void onMessage(Message message) {
		try {
			QueueMessage queueMessage = (QueueMessage)XMLUtil.unmarchall(
					getByteArrayFromJmsMessage((BytesMessage)message), QueueMessage.class);

			System.out.println("---- msg inMDB...");
			System.out.print("---- 1 " + queueMessage.getHeader().value.getVerb());
			System.out.print("---- 2 " + queueMessage.getHeader().value.getNoun());
			System.out.println("---- 3 " + queueMessage.getHeader().value.getUser().getUserID());
			
			String ticket = Completer.extractTicket(queueMessage.getHeader());
			System.out.println("---- MDB comprobando ticket: " + ticket);

			processMessage( queueMessage );
			System.out.println("---- MDB Mensaje procesado, ticket: " + ticket);
		} catch( JMSException e ) {
            e.printStackTrace();            
        } catch( Throwable e ) {
        	e.printStackTrace();        	
        }
	}

	private void processMessage( QueueMessage queueMessage ) {
		try {
			Holder<HeaderType> header = queueMessage.getHeader();
			// obtener ticket del header.
			String ticket = Completer.extractTicket(header);
			
			// Desde el queueMessage determinar de que operacion se trata
			queueMessage.getHeader().value = Completer.constructExecEndDeviceControlsHeader(CIMVerb.CREATE_VERB);
			Completer.putTicket(header, ticket);

			// Extract useful values from request and use it.
			Holder<EndDeviceControlsPayloadType> payload = queueMessage.getPayload();
			
			// Aqui en lugar de hacer el fill, se debe hacer la consulta y guardar en la tabla h2.
			IExecEndDeviceControlsService execEndDeviceControlsService = ExecEndDeviceControlsService.getInstance(dataSource);
			ResEndDeviceControls resEndDeviceControls = execEndDeviceControlsService.getOperations(payload.value, ticket, header.value);
			tmpTableEJB.saveEndDeviceControls(resEndDeviceControls);

		} catch (Exception e) {
			e.printStackTrace();
			if (context != null) {
				context.setRollbackOnly();
			}
		}

	}

	/**
	 * 
	 * @param bytesMessage
	 * @return
	 * @throws JMSException
	 */
	private byte[] getByteArrayFromJmsMessage(BytesMessage bytesMessage) throws JMSException {
		byte data[] = new byte[(int) bytesMessage.getBodyLength()];
		bytesMessage.readBytes(data);
		return data;
	}

}
